package com.way.capture.activity;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageButton;

import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import com.way.capture.R;
import com.way.capture.base.BaseActivity;
import com.way.capture.utils.Utils;

import butterknife.BindView;

public class VideoActivity extends BaseActivity {
    private static final String TAG = "VideoActivity";
    private static final String ARG_IMAGE_PATH = "arg_image_path";
    @BindView(R.id.root_view)
    View mRootView;
    @BindView(R.id.controls)
    View mControlView;
    @BindView(R.id.play_pause)
    ImageButton mPlayPauseButton;
    @BindView(R.id.toolbar)
    Toolbar mToolbar;
    private SimpleExoPlayer mExoPlayer;
    private long mPlayerPosition = -1;
    private Uri mVideoUri;

    public static void startVideoActivity(Activity context, String path, View imageView) {
        Intent i = new Intent(context, VideoActivity.class);
        i.putExtra(ARG_IMAGE_PATH, path);
        context.startActivity(i);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mVideoUri = Uri.parse(getIntent().getStringExtra(ARG_IMAGE_PATH));
        if (mVideoUri == null) {
            finish();
        }
        if (Utils.isNotch) {
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams
                    .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            getWindow().setAttributes(lp);
        }
        //needed to achieve transparent navBar
        showOrHideSystemUi(true);
        initToolbar();
        initPlayControlView();
    }

    @Override
    protected int getContentView() {
        return R.layout.activity_video;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                break;
            default:
                break;
        }
        return true;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setWindowInsets();
    }

    private void initToolbar() {
        setSupportActionBar(mToolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
    }

    private void initPlayControlView() {
        Log.d(TAG, "initPlayControlView: getNavigationBarHeight = " + Utils.getNavigationBarHeight());
        mPlayPauseButton.setImageResource(R.drawable.pause_to_play_avd);
        mPlayPauseButton.setOnClickListener(view -> {
            if (mExoPlayer != null) {
                mExoPlayer.setPlayWhenReady(!mExoPlayer.getPlayWhenReady());
            }
        });

        setWindowInsets();

        //hide & show Nav-/StatusBar together with controls
        final PlayerControlView playerControlView = (PlayerControlView) mControlView.getParent();
        playerControlView.setVisibilityListener(new PlayerControlView.VisibilityListener() {
            @Override
            public void onVisibilityChange(final int visibility) {
                //animate Toolbar & controls
                if (visibility != View.VISIBLE) {
                    //make view visible again, so the Animation is visible
                    playerControlView.setVisibility(View.VISIBLE);
                }

                float toolbarTranslationY = visibility == View.VISIBLE ? 0
                        : -(mToolbar.getHeight());
                mToolbar.animate()
                        .translationY(toolbarTranslationY)
                        .setInterpolator(new AccelerateDecelerateInterpolator())
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                super.onAnimationEnd(animation);
                                playerControlView.setVisibility(visibility);
                            }
                        })
                        .start();

                float controlsTranslationY = visibility == View.VISIBLE ? 0
                        : mControlView.getHeight();
                mControlView.animate()
                        .translationY(controlsTranslationY)
                        .setInterpolator(new AccelerateDecelerateInterpolator())
                        .start();

                //show/hide Nav-/StatusBar
                showOrHideSystemUi(visibility == View.VISIBLE);
            }
        });
    }

    public void setWindowInsets() {
        mRootView.setOnApplyWindowInsetsListener((view, insets) -> {

            mToolbar.setPadding(insets.getSystemWindowInsetLeft(),
                    insets.getSystemWindowInsetTop(),
                    insets.getSystemWindowInsetRight(), 0);

            mControlView.setPadding(insets.getSystemWindowInsetLeft() + Utils.dp2px(8),
                    Utils.dp2px(8), insets.getSystemWindowInsetRight() + Utils.dp2px(8),
                    insets.getSystemWindowInsetBottom() + Utils.dp2px(8));

            // clear this listener so insets aren't re-applied
            mRootView.setOnApplyWindowInsetsListener(null);
            return insets.consumeSystemWindowInsets();
        });

    }

    public void showOrHideSystemUi(boolean show) {
        if (show) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE);
        } else {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                            | View.SYSTEM_UI_FLAG_IMMERSIVE
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        initPlayer();
        if (mPlayerPosition != -1) {
            mExoPlayer.seekTo(mPlayerPosition);
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        this.finish();
    }

    private void initPlayer() {
        // Produces DataSource instances through which media data is loaded.
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
                Util.getUserAgent(this, getString(R.string.app_name)));
        // This is the MediaSource representing the media to be played.
        MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(mVideoUri);

        // Create the mExoPlayer
        mExoPlayer = ExoPlayerFactory.newSimpleInstance(this);

        // Bind the mExoPlayer to the view.
        PlayerView playerView = findViewById(R.id.exoPlayerView);
        playerView.setPlayer(mExoPlayer);

        // Prepare the mExoPlayer with the source.
        mExoPlayer.prepare(videoSource);
        mExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
        mExoPlayer.setPlayWhenReady(true);

        final ImageButton playPause = findViewById(R.id.play_pause);
        mExoPlayer.addListener(new SimpleEventListener() {
            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                //update PlayPause-Button
                if (mExoPlayer.getPlayWhenReady()) {
                    playPause.setImageResource(R.drawable.play_to_pause_avd);
                } else {
                    playPause.setImageResource(R.drawable.pause_to_play_avd);
                }

                Drawable d = playPause.getDrawable();
                if (d instanceof Animatable) {
                    ((Animatable) d).start();
                }
            }
        });
    }

    @Override
    protected void onStop() {
        super.onStop();

        if (mExoPlayer != null) {
            mPlayerPosition = mExoPlayer.getCurrentPosition();
            mExoPlayer.stop();
            mExoPlayer.release();
            mExoPlayer = null;
        }
    }

    public static class SimpleEventListener implements Player.EventListener {

        @Override
        public void onTracksChanged(TrackGroupArray trackGroupArray, TrackSelectionArray trackSelectionArray) {

        }

        @Override
        public void onLoadingChanged(boolean isLoading) {

        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

        }

        @Override
        public void onRepeatModeChanged(int repeatMode) {

        }

        @Override
        public void onPlayerError(ExoPlaybackException error) {

        }

        @Override
        public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

        }
    }
}
